﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using LogLib;
using KAImage;
using KAImage.Config;
using PipeClient;

namespace KProcessor
{
    public delegate bool ControlCtrlDelegate(int CtrlType);
    class Program
    {
        protected static IntPtr ParentFormHandle = IntPtr.Zero;
        /// <summary>
        /// 指示是否已经通知主窗体加载完成
        /// </summary>
        protected static bool _bNotified = false;
        public static string AppName = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
        private static InitComponents _components = new InitComponents();
        private static PhotoDetectServer _server = null;
        private static PhotoDetecting _detector = null;
        public static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                string arg = args[0];
                if (!string.IsNullOrEmpty(arg))
                {
                    ParentFormHandle = (IntPtr)Int32.Parse(arg);
                }
            }

            string fileName = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
            Console.Title = fileName;
            IntPtr ParenthWnd = new IntPtr(0);
            IntPtr et = new IntPtr(0);
            ParenthWnd = FindWindow(null, fileName);
            //隐藏本dos窗体, 0: 后台执行；1:正常启动；2:最小化到任务栏；3:最大化 
            ShowWindow(ParenthWnd, 2);
            LoadConfig();
            bool bRet = SetConsoleCtrlHandler(newDelegate, true);
            if (_components.Init())
            {
                TraceWorkingState("PXL引擎初始化成功!");
                OnAppStartupFinished();
                StartServer();
            }
            else
            {
                TraceWorkingState(_components.strErrInfo);
                OnAppStartupFinished(0, _components.strErrInfo);
                Thread.Sleep(3000);
            }
            _components.Close();
        }

        public static void StartServer()
        {
            _detector = new PhotoDetecting();
            _server = new PhotoDetectServer("test_pipe");
            _server.Detecting += _detector.OnHandling;
            _detector.AppExited += _server.Stop;
            _server.Start();
        }

        public static void TraceWorkingState(string info)
        {
            string timeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffffff");
            Console.WriteLine(timeStamp + "\t" + info);
        }


        /// <summary>
        /// 通知主窗体该进程启动已经完成
        /// </summary>
        protected static void OnAppStartupFinished(int code = 1, string msg = "程序加载成功")
        {
            // 当父窗体为空时，不需要通知
            if (IntPtr.Zero == ParentFormHandle || _bNotified)
            {
                Log.WriteAsync(string.Format("{0}获取父进程主窗口句柄为空，不启用进程监测.", AppName));
                return;
            }
            string sendMsg = string.Format("{0}#{1}#{2}", AppName, code, msg);
            Pipe t = new Pipe(4, sendMsg, "MainStartup");
            Task.Factory.StartNew(new Action(t.run));
            Log.WriteAsync("已经通知主窗体启动完成: " + AppName);
            _bNotified = true;
        }

        private static void LoadConfig()
        {
            ConfigFiles.Initialize();
            ConfigService service = ConfigService.GetInstance();
            if (!service.CheckLoadAllSuccess())
            {
                string[] errArray = service.GetLoadErrors();
                string title = "部分参数加载异常，详细异常信息如下:";
                Log.WriteAsync(title);
                foreach (string info in errArray)
                {
                    Log.WriteAsync(info);
                }
            }
        }

        #region Handle the Close Event

        [DllImport("kernel32.dll")]
        private static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate HandlerRoutine, bool Add);

        public static ControlCtrlDelegate newDelegate = new ControlCtrlDelegate(HandlerRoutine);

        public static bool HandlerRoutine(int CtrlType)
        {
            switch (CtrlType)
            {
                case 0:
                    Console.WriteLine("0工具被强制关闭"); //Ctrl+C关闭  
                    //相关代码执行
                    break;
                case 2:
                    Console.WriteLine("2工具被强制关闭");//按控制台关闭按钮关闭 
                    //相关代码执行 
                    _components.Close();
                    break;
            }
            return false;
        }
        #endregion

        #region Windows API
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]   //找子窗体   
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("User32.dll", EntryPoint = "SendMessage")]   //用于发送信息给窗体   
        private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

        [DllImport("User32.dll", EntryPoint = "ShowWindow")]   //
        private static extern bool ShowWindow(IntPtr hWnd, int type);
        #endregion
    }
}
